import { guarded, json } from "@/lib/api"; import { getConversation, getActiveMessages } from "@/lib/chat/store"; import type { Part } from "@/lib/ai/types"; export const GET = guarded<{ id: string }>(async (req, { params }) => { const conv = await getConversation(params.id); if (!conv) return json({ error: "Introuvable" }, { status: 404 }); const messages = await getActiveMessages(params.id); const fmt = req.nextUrl.searchParams.get("format") ?? "md"; const safe = conv.title.replace(/[^\w\- àâçéèêëîïôûùüÿœ]/gi, "_").slice(0, 60); if (fmt === "json") return new Response(JSON.stringify({ conversation: conv, messages }, null, 2), { headers: { "content-type": "application/json", "content-disposition": `attachment; filename="${safe}.json"` } }); const lines = [`# ${conv.title}`, "", `_Exporté le ${new Date().toLocaleString("fr-CA")} — ${messages.length} messages_`, ""]; for (const m of messages) { lines.push(`## ${m.role === "user" ? "Vous" : `Assistant${m.model_id ? ` (${m.model_id})` : ""}`}`, ""); for (const p of m.parts as Part[]) { if (p.type === "text") lines.push(p.text, ""); else if (p.type === "tool_call") lines.push(`> 🔧 ${p.name}(${JSON.stringify(p.input)}) → ${p.status}`, ""); else if (p.type === "file" || p.type === "image") lines.push(`> 📎 ${"name" in p ? p.name : p.attachmentId}`, ""); else if (p.type === "generated_image") lines.push(`> 🖼️ image générée (${p.model}) : ${p.prompt}`, ""); } if (m.role === "assistant" && m.usage) lines.push(`${m.usage.input} → ${m.usage.output} jetons · ${m.cost_usd != null ? `$${Number(m.cost_usd).toFixed(4)}` : "coût inconnu"} · ${m.latency_ms} ms`, ""); } return new Response(lines.join("\n"), { headers: { "content-type": "text/markdown; charset=utf-8", "content-disposition": `attachment; filename="${safe}.md"` } }); });